#include <fstream> 	// file stream
#include <iostream>	// io stream
#include <string>	
#include <stdlib.h>
#include <time.h> 
using namespace std;

int main() 
{ 

// training data
	ifstream inFile; 
	inFile.open("data2.txt"); // open file
	double* x1 = new double[500];
	double* x2 = new double[500];
	double* x3 = new double[500];
	double* x4 = new double[500];
	double*	y0 = new double[500];
	int n1, n2, n3, n4, k;
	n1 = n2 = n3 = n4 = k = 0;
	if(inFile.is_open()){
		while(!inFile.eof()){ 	
			inFile >> x1[n1++];
			inFile >> x2[n2++];
			inFile >> x3[n3++];
			inFile >> x4[n4++];
			inFile >> y0[k++];
		} 
	} 
	inFile.close(); 

// testing data
	ifstream inFile_t; 
	inFile_t.open("test.txt"); // open file
	double* x1_t = new double[500];
	double* x2_t = new double[500];
	double* x3_t = new double[500];
	double* x4_t = new double[500];
	double*	y0_t = new double[500];
	int n1_t, n2_t, n3_t, n4_t, k_t;
	n1_t = n2_t = n3_t = n4_t = k_t = 0;
	if(inFile_t.is_open()){
		while(!inFile_t.eof()){ 
			inFile_t >> x1_t[n1_t++];
			inFile_t >> x2_t[n2_t++];
			inFile_t >> x3_t[n3_t++];
			inFile_t >> x4_t[n4_t++];
			inFile_t >> y0_t[k_t++];
		} 
	} 
	inFile_t.close(); 

	int error_total = 0;
	double epsilon = 1;

	for(int t = 0; t < 2000; t++)
	{

		// pocket data
		double w0p, w1p, w2p, w3p, w4p;
		w0p = w1p = w2p = w3p = w4p = 0;
		int p_error = 500;
		int total_updates = 0;

		double w0, w1, w2, w3, w4;
		w0 = w1 = w2 = w3 = w4 = 0;

		// random input data order
		srand((unsigned) time(NULL));
		int j = 500;
		while(j--)
		{
			int index = rand() % 500;
			double temp;
			temp = x1[index];
			x1[index] = x1[0];
			x1[0] = temp;

			temp = x2[index];
			x2[index] = x2[0];
			x2[0] = temp;

			temp = x3[index];
			x3[index] = x3[0];
			x3[0] = temp;

			temp = x4[index];
			x4[index] = x4[0];
			x4[0] = temp;

			temp = y0[index];
			y0[index] = y0[0];
			y0[0] = temp;
		}
		srand((unsigned) time(NULL));
		int d = 0;
		while(1) // halts until no more mistakes
		{
			int i = rand() % 500;// pick an input randomly
			//cout << "i = " << i << endl;
			double temp = w0 + w1 * x1[i] + w2 * x2[i] + w3 * x3[i] + w4 * x4[i]; // w(t) * x(n)
			double s = y0[i];

			if(temp == 0) temp = -1;
			
			if( temp*s > 0  ) // approve: sign(w(t) * x(n) > threshold
			{
				//cout << " approve ";
				continue;
			}
			else // deny: sign(w(t) * x(n)) < threshold
			{
				// w(t+1) = w(t) + y(n)*x(n)
				//cout << "deny" ;
				w0 += s*epsilon;
				w1 += s * x1[i]*epsilon;
				w2 += s * x2[i]*epsilon;
				w3 += s * x3[i]*epsilon;
				w4 += s * x4[i]*epsilon;
				total_updates++;
			}
			//cout << "w0 = " << w0 << " w1 = " << w1 << " w2 = " << w2 << " w3 = " << w3 << " w4 = " << w4;
			//system("pause");
			// verifaction
			int v_error = 0;
			for(int i = 0; i<500; i++)
			{
				double temp2 = w0 + w1 * x1[i] + w2 * x2[i] + w3 * x3[i] + w4 * x4[i];
				double s2 = y0[i];
				if(temp2 == 0) temp = -1;
				if(temp2*s2 < 0) v_error++;
			}

			// if if wt+1 makes fewer mistakes than w_pocket, replace w_pocket by wt+1
			if(v_error < p_error)
			{
				w0p = w0;
				w1p = w1;
				w2p = w2;
				w3p = w3;
				w4p = w4;
				p_error = v_error;
			}

			if(total_updates == 100) // stop updates afrer 50 iterations
			{
				// w0p = w0;
				// w1p = w1;
				// w2p = w2;
				// w3p = w3;
				// w4p = w4;
				// p_error = v_error;
				break;
			}
		}
		
		cout << "w0p = " << w0p << " w1p = " << w1p << " w2p = " << w2p << " w3p = " << w3p << " w4p = " << w4p << endl;
		error_total += p_error;
	}

	cout << "total average is " << (double)error_total/(double)(2000*500) << endl;

	system("pause");

	return 0;

} 